package org.hy.demo.design.door;


import com.alibaba.fastjson.JSON;
import org.apache.commons.beanutils.BeanUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.hy.demo.design.door.annotation.DoDoor;
import org.hy.demo.design.door.config.StarterService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
public class DoJoinPoint {

    private Logger logger = LoggerFactory.getLogger(DoJoinPoint.class);

    @Autowired
    private StarterService starterService;

    @Pointcut("@annotation(org.hy.demo.design.door.annotation.DoDoor)")
    public void aopPoint() {

    }

    @Around("aopPoint()")
    public Object doRouter(ProceedingJoinPoint joinPoint) throws Throwable {

        Method method = getMethod(joinPoint);
        DoDoor door = method.getAnnotation(DoDoor.class);

        String keyValue = getFiledValue(door.key(), joinPoint.getArgs());
        logger.info("itstack door handler method：{} value：{}", method.getName(), keyValue);

        if (null == keyValue || "".equals(keyValue)) return joinPoint.proceed();

        String[] split = starterService.split(",");
        for (String str : split) {
            if (keyValue.equals(str)) {
                return joinPoint.proceed();
            }
        }

        return returnObject(door, method);
    }


    private Method getMethod(JoinPoint joinPoint) throws NoSuchMethodException{

        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        return getClass(joinPoint).getMethod(methodSignature.getName(), methodSignature.getParameterTypes());
    }

    private Class<? extends Object> getClass(JoinPoint joinPoint) throws NoSuchMethodException  {
        return joinPoint.getTarget().getClass();
    }


    private Object returnObject(DoDoor doGate, Method method) throws IllegalAccessException, InstantiationException {
        Class<?> returnType = method.getReturnType();

        String returnJson = doGate.returnJson();
        if ("".equals(returnJson)){
            return returnType.newInstance();
        }
        return JSON.parseObject(returnJson, returnType);
    }

    private String getFiledValue(String filed, Object[] args) {

        String filedValue = null;

        for (Object arg : args) {

            try {
                if (null == filedValue || "".equals(filedValue)) {
                    filedValue = BeanUtils.getProperty(arg, filed);
                } else {
                    break;
                }
            }catch (Exception e){
                if (args.length == 1){
                    return args[0].toString();
                }
            }
        }
        return filedValue;
    }
}
